#include "pch.hpp"
#include "CssHighlighter.hpp"




CssHighlighter::CssHighlighter(QTextDocument *document)
	: QSyntaxHighlighter(document)
	, m_errorModel(NULL)
{
	m_font.setFamily("Courier New");
	m_font.setFixedPitch(true);
	m_font.setPointSize(10);


	m_normalFormat.setFont(m_font);
	m_attributeFormat.setFont(m_font);
	m_classFormat.setFont(m_font);
	m_stateFormat.setFont(m_font);
	m_singleLineCommentFormat.setFont(m_font);
	m_multiLineCommentFormat.setFont(m_font);
	m_quotationFormat.setFont(m_font);


	m_attributeFormat.setForeground(QColor("#FF352B"));

	HighlightingRule rule;
	QStringList keywordPatterns;
	keywordPatterns << "\\bbackground-color\\b" << "\\bbackground-image\\b" << "\\bbackground-image-l\\b"
		<< "\\bbackground-image-tl\\b" << "\\bbackground-image-t\\b" << "\\bbackground-image-tr\\b"
		<< "\\bbackground-image-r\\b" << "\\bbackground-image-br\\b" << "\\bbackground-image-b\\b"
		<< "\\bbackground-image-bl\\b" << "\\bforeground-color\\b" << "\\bforeground-image\\b"
		<< "\\bforeground-image-l\\b" << "\\bforeground-image-tl\\b" << "\\bforeground-image-t\\b"
		<< "\\bforeground-image-tr\\b" << "\\bforeground-image-r\\b" << "\\bforeground-image-br\\b"
		<< "\\bforeground-image-b\\b" << "\\bforeground-image-bl\\b" << "\\bfont\\b"
		<< "\\bfont-color\\b" << "\\bfont-style\\b" << "\\bfont-size\\b"
		<< "\\bfont-weight\\b" << "\\bmin-width\\b" << "\\bmax-width\\b"
		<< "\\bmin-height\\b" << "\\bmax-height\\b" << "\\bresizing\\b";

	foreach(const QString &pattern, keywordPatterns)
	{
		rule.pattern = QRegExp(pattern);
		rule.format = m_attributeFormat;
		m_highlightingRules << rule;
	}

	m_classFormat.setForeground(QColor("#91190A"));
	keywordPatterns.clear();
	keywordPatterns << "\\btext\\b" << "\\bconsole\\b" << "\\bdesktop\\b" << "\\bpush-button\\b"
		<< "\\bframe\\b" << "\\bline-edit\\b" << "\\bprogress-bar\\b" << "\\bwindow\\b" << "\\bdialog\\b";

	foreach(const QString& pattern, keywordPatterns)
	{
		rule.pattern = QRegExp(pattern);
		rule.format = m_classFormat;
		m_highlightingRules << rule;
	}

	m_stateFormat.setForeground(QColor("#0000FF"));
	keywordPatterns.clear();
	keywordPatterns << "\\bhovered\\b" << "\\bactive\\b";

	foreach(const QString& pattern, keywordPatterns)
	{
		rule.pattern = QRegExp(pattern);
		rule.format  = m_stateFormat;
		m_highlightingRules << rule;
	}

	m_quotationFormat.setForeground(QColor("#A31515"));
	rule.pattern = QRegExp("\".*\"");
	rule.format = m_quotationFormat;
	m_highlightingRules.append(rule);

	m_singleLineCommentFormat.setForeground(QColor("#008000"));
	m_singleLineCommentFormat.setBackground(QColor("#A5E38A"));
	rule.pattern = QRegExp("//[^\n]*");
	rule.format = m_singleLineCommentFormat;
	m_highlightingRules.append(rule);

	m_multiLineCommentFormat.setForeground(QColor("#008000"));
	m_multiLineCommentFormat.setBackground(QColor("#A5E38A"));

	m_commentStartExpression = QRegExp("/\\*");
	m_commentEndExpression = QRegExp("\\*/");
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void CssHighlighter::setErrorModel(ErrorModel* errorModel)
{
	m_errorModel = errorModel;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void CssHighlighter::highlightBlock(const QString &text)
{
	// First, all text is formatted using the standard formatting
	// and only in a second step, those parts that match special stuff
	// will be formatted using their special formatting rule
	setFormat(0, text.size(), m_normalFormat);

	foreach(const HighlightingRule &rule, m_highlightingRules)
	{
		QRegExp expression(rule.pattern);
		int index = expression.indexIn(text);

		while(index >= 0)
		{
			int length = expression.matchedLength();
			setFormat(index, length, rule.format);
			index = expression.indexIn(text, index + length);
		}
	}

	setCurrentBlockState(0);

	int startIndex = 0;
	if(previousBlockState() != 1)
		startIndex = m_commentStartExpression.indexIn(text);

	while(startIndex >= 0)
	{
		int endIndex = m_commentEndExpression.indexIn(text, startIndex);
		int commentLength;

		if(endIndex == -1)
		{
			setCurrentBlockState(1);
			commentLength = text.length() - startIndex;
		}
		else
		{
			commentLength = endIndex - startIndex + m_commentEndExpression.matchedLength();
		}

		setFormat(startIndex, commentLength, m_multiLineCommentFormat);
		startIndex = m_commentStartExpression.indexIn(text, startIndex + commentLength);
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////

QFont CssHighlighter::font() const
{
	return m_font;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
